import { deviceTreeControllerDeviceTree as getTreeList } from '@/services/ess/deviceTree';
import { SearchOutlined } from '@ant-design/icons';
import { useIntl } from '@umijs/max';
import { useSize } from 'ahooks';
import { Input, Tree } from 'antd';
import type { DataNode, EventDataNode } from 'antd/es/tree';
import { debounce } from 'lodash';
import React, { forwardRef, useEffect, useState } from 'react';
import styles from '../index.less';

interface TreeProps {
  handleClick?: (
    deviceCode: any,
    treeData: any,
    deviceType: string | null,
    nodeType: string,
    areaId?: string,
  ) => void;
  deleteCall?: () => void;
  defaultExpandedKeys?: string[];
  defaultSelectedKeys?: string[];
  onNodeSelect?: (selectedKeys: string[]) => void;
}

interface TreeNode extends EventDataNode<DataNode> {
  deviceCode: string;
  deviceName: string;
  deviceType: string | null;
  nodeType: string;
  areaId?: string;
  subDevices?: TreeNode[];
}

const TreeList = forwardRef(
  (
    { handleClick, defaultExpandedKeys = [], defaultSelectedKeys = [], onNodeSelect }: TreeProps,
    ref: any,
  ) => {
    const [treeData, setTreeData] = useState<TreeNode[]>([]);
    const [treeALL, setTreeALL] = useState<TreeNode[]>([]);
    const [expandedKeys, setExpandedKeys] = useState<string[]>(defaultExpandedKeys);
    const [autoExpandParent, setAutoExpandParent] = useState<boolean>(true);
    const [selectNodeID, setSelectNodeID] = useState<string>('');
    const [selectDeviceType, setSelectDeviceType] = useState<string | null>(null);
    const [selectNodeDeviceId, setSelectNodeDeviceId] = useState<string>('');
    const [selectNodeType, setSelectNodeType] = useState<string>('');
    const [isRootNode, setIsRootNode] = useState<boolean>(false);
    const [, setDeviceName] = useState<string>('');
    const intl = useIntl();
    console.log(
      '111',
      selectDeviceType,
      selectNodeDeviceId,
      selectNodeType,
      isRootNode,
      selectNodeID,
    );
    const treeContainerRef = React.useRef<HTMLDivElement>(null);
    const size = useSize(treeContainerRef);
    const addUniqueKeyToNodes = (nodes: TreeNode[], prefix = 'node_'): TreeNode[] => {
      return nodes.map((node, index) => {
        const newNode: TreeNode = {
          ...node,
          key: `${prefix}${index}`,
        };
        if (newNode.subDevices) {
          newNode.subDevices = addUniqueKeyToNodes(newNode.subDevices, `${newNode.key}_`);
        }
        return newNode;
      });
    };

    const findNodeByKey = (nodes: TreeNode[], key: string): TreeNode | undefined => {
      for (const node of nodes) {
        if (node.key === key) {
          return node;
        }
        if (node.subDevices) {
          const found = findNodeByKey(node.subDevices, key);
          if (found) {
            return found;
          }
        }
      }
      return undefined;
    };

    const queryTreeList = async () => {
      let result: any = await getTreeList({ needGroupNode: 'true' });
      console.log('getTreeList result:', result);
      if (result && result.success) {
        const wrappedData = addUniqueKeyToNodes([result.data]);
        console.log('Wrapped tree data:', wrappedData);
        setTreeData(wrappedData);
        setTreeALL(wrappedData);
        if (wrappedData.length > 0) {
          setSelectNodeID(wrappedData[0].key as string);
          // eslint-disable-next-line @typescript-eslint/no-unused-expressions
          handleClick &&
            handleClick(
              wrappedData[0].deviceCode,
              wrappedData,
              wrappedData[0].deviceType,
              wrappedData[0].nodeType,
              wrappedData[0].areaId,
            );
          setIsRootNode(true);
        }
      }
    };

    const getParentKeys = (nodes: TreeNode[], keyword: string): string[] => {
      let parentKeys: string[] = [];
      const traverse = (node: TreeNode, parents: string[]) => {
        if (node.deviceName.includes(keyword)) {
          parentKeys = parentKeys.concat(parents);
        }
        if (node.subDevices) {
          node.subDevices.forEach((subNode) => {
            traverse(subNode, parents.concat(node.key as string));
          });
        }
      };
      nodes.forEach((node) => traverse(node, []));
      return parentKeys;
    };

    const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
      const { value } = e.target;
      setDeviceName(value);

      const filterTreeData = (nodes: TreeNode[], keyword: string): TreeNode[] => {
        return nodes
          .map((node): TreeNode | null => {
            if (node.deviceName.includes(keyword)) {
              return node;
            }
            if (node.subDevices) {
              const filteredSubDevices: TreeNode[] = filterTreeData(node.subDevices, keyword);
              if (filteredSubDevices.length > 0) {
                return { ...node, subDevices: filteredSubDevices };
              }
            }
            return null;
          })
          .filter((node): node is TreeNode => node !== null);
      };

      const filteredData = filterTreeData(treeALL, value);
      setTreeData(filteredData);

      const newExpandedKeys = getParentKeys(treeALL, value);
      setExpandedKeys(newExpandedKeys);
      setAutoExpandParent(true);
    };

    const TreeSelectMethod = (
      selectedKeys: React.Key[],
      info: {
        event: 'select';
        selected: boolean;
        node: EventDataNode<TreeNode>;
        selectedNodes: TreeNode[];
        nativeEvent: MouseEvent;
      },
    ) => {
      if (selectedKeys.length === 0) {
        return;
      }
      // @ts-ignore
      // eslint-disable-next-line @typescript-eslint/no-unused-expressions
      handleClick &&
        handleClick(
          info.node.deviceCode,
          treeALL,
          info.node.deviceType,
          info.node.nodeType,
          info.node.areaId,
        );
      setSelectNodeID(info.node.key as string);
      setSelectDeviceType(info.node.deviceType);
      setSelectNodeType(info.node.nodeType);
      setSelectNodeDeviceId(info.node.deviceCode);

      const isRoot = treeData.length > 0 && treeData[0].key === info.node.key;
      setIsRootNode(isRoot);

      if (onNodeSelect) {
        onNodeSelect(selectedKeys as string[]);
      }
    };

    useEffect(() => {
      queryTreeList();
    }, []);

    useEffect(() => {
      if (defaultSelectedKeys.length > 0 && treeData.length > 0) {
        console.log('defaultSelectedKeys:', defaultSelectedKeys);
        const selectedNode = findNodeByKey(treeData, defaultSelectedKeys[0]);
        if (selectedNode) {
          console.log('Triggering TreeSelectMethod for default selected node:', selectedNode);
          TreeSelectMethod(defaultSelectedKeys, {
            event: 'select',
            selected: true,
            node: selectedNode as EventDataNode<TreeNode>,
            selectedNodes: [],
            nativeEvent: new MouseEvent('click'),
          });
        } else {
          console.log('No matching node found for key:', defaultSelectedKeys[0]);
        }
      }
    }, [defaultSelectedKeys, treeData]);

    useEffect(() => {
      setExpandedKeys(defaultExpandedKeys);
    }, [defaultExpandedKeys]);

    return (
      <div className={styles.treeWrap} ref={ref}>
        <div className={styles.treeTop}>
          <Input
            style={{ marginBottom: 8 }}
            placeholder={intl.formatMessage({ id: 'siteManage.enterPlease' })}
            addonAfter={<SearchOutlined />}
            onChange={debounce(onChange, 300)}
            className={styles.tree_search}
          />
          <div
            className={styles.tree}
            ref={treeContainerRef}
            style={{ flex: 1, overflowX: 'auto' }}
          >
            {treeData.length > 0 && (
              <Tree
                height={size?.height || 0}
                defaultExpandAll={true}
                blockNode
                defaultSelectedKeys={defaultSelectedKeys}
                expandedKeys={expandedKeys}
                autoExpandParent={autoExpandParent}
                fieldNames={{ title: 'deviceName', key: 'key', children: 'subDevices' }}
                treeData={treeData}
                onSelect={TreeSelectMethod}
                onExpand={(keys) => {
                  setExpandedKeys(keys.map(String));
                  setAutoExpandParent(false);
                }}
                titleRender={(data: TreeNode) => {
                  return <div style={{ lineHeight: '32px' }}>{data.deviceName}</div>;
                }}
              />
            )}
          </div>
        </div>
      </div>
    );
  },
);

export default TreeList;
